package cn.com.pagoda.ideplugin.ui;

import cn.com.pagoda.ideplugin.service.JsonEditorService;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.util.ui.UIUtil;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextarea.SearchContext;
import org.fife.ui.rtextarea.SearchEngine;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

/**
 * JSON编辑
 *
 * @author tianmingxing <mx.tian@qq.com> on 2023-05-06
 */
public class JsonEditorPanel implements ActionListener {

    private final JsonEditorService service;
    private final AnActionEvent anActionEvent;
    private final JPanel panel;
    private final JButton formatBtn;
    private final JButton compactBtn;
    private final JButton toClassBtn;
    private final JButton resetBtn;
    private final RSyntaxTextArea textArea;
    private final JButton nextButton;
    private final JCheckBox regexCB;
    private final JCheckBox matchCaseCB;
    private final JButton prevButton;
    private final JTextField searchField;

    public JsonEditorPanel(AnActionEvent anActionEvent, JPanel mainPanel) {
        this.anActionEvent = anActionEvent;
        panel = new JPanel(new BorderLayout());
        panel.setSize(800, 800);
        this.service = new JsonEditorService(anActionEvent, panel);

        JPanel toolsPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        JToolBar toolBar = new JToolBar();
        toolBar.setBorder(BorderFactory.createEmptyBorder());
        searchField = new JTextField(10);
        toolBar.add(searchField);
        nextButton = new JButton("Find Next");
        nextButton.addActionListener(this);
        toolBar.add(nextButton);
        searchField.addActionListener(e -> nextButton.doClick(0));
        prevButton = new JButton("Find Previous");
        prevButton.addActionListener(this);
        toolBar.add(prevButton);
        regexCB = new JCheckBox("Regex");
        toolBar.add(regexCB);
        matchCaseCB = new JCheckBox("Match Case");
        toolBar.add(matchCaseCB);
        toolBar.setFloatable(false);
        toolsPanel.add(toolBar);

        formatBtn = new JButton("Format");
        formatBtn.addActionListener(this);
        toolsPanel.add(formatBtn);
        compactBtn = new JButton("Compact");
        compactBtn.addActionListener(this);
        toolsPanel.add(compactBtn);
        toClassBtn = new JButton("To Class");
        toClassBtn.addActionListener(this);
        toClassBtn.setEnabled(false);
        toolsPanel.add(toClassBtn);
        resetBtn = new JButton("Reset");
        resetBtn.addActionListener(this);
        toolsPanel.add(resetBtn);

        textArea = new RSyntaxTextArea(40, 50);
        textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON);
        textArea.setCodeFoldingEnabled(true);
        textArea.setAntiAliasingEnabled(true);
        textArea.setTabsEmulated(true);
        textArea.setMarkOccurrences(true);
        textArea.setTabSize(4);
        var font = new Font("Microsoft YaHei", Font.PLAIN, 14);
        textArea.setFont(font);

        // 获取当前主题的名称
        String currentTheme = UIUtil.isUnderDarcula() ? "Dark" : "Light";
        try {
            if ("Dark".equals(currentTheme)) {
                Theme theme = Theme.load(getClass().getResourceAsStream(
                        "/org/fife/ui/rsyntaxtextarea/themes/dark.xml"));
                theme.apply(textArea);
            } else {
                Theme theme = Theme.load(getClass().getResourceAsStream(
                        "/org/fife/ui/rsyntaxtextarea/themes/idea.xml"));
                theme.apply(textArea);
            }
        } catch (IOException ignored) {
        }

        RTextScrollPane scrollPane = new RTextScrollPane(textArea);
        scrollPane.setLineNumbersEnabled(true);
        scrollPane.setFoldIndicatorEnabled(true);

        panel.add(toolsPanel, BorderLayout.NORTH);
        panel.add(scrollPane, BorderLayout.CENTER);

        mainPanel.add(panel, getClass().getSimpleName());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == formatBtn) {
            formatBtn.setEnabled(false);
            textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON);
            textArea.setText(service.jsonHandler(textArea.getText(), true));
            formatBtn.setEnabled(true);
            toClassBtn.setEnabled(true);
        } else if (e.getSource() == compactBtn) {
            compactBtn.setEnabled(false);
            textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON);
            textArea.setText(service.jsonHandler(textArea.getText(), false));
            compactBtn.setEnabled(true);
            toClassBtn.setEnabled(true);
        } else if (e.getSource() == toClassBtn) {
            toClassBtn.setEnabled(false);
            formatBtn.setEnabled(false);
            compactBtn.setEnabled(false);
            textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
            textArea.setText(service.toClassHandler(textArea.getText()));
            toClassBtn.setEnabled(true);
        } else if (e.getSource() == resetBtn) {
            formatBtn.setEnabled(true);
            compactBtn.setEnabled(true);
            toClassBtn.setEnabled(false);
            textArea.setText("{}");
        } else if (e.getSource() == nextButton || e.getSource() == prevButton) {
            SearchContext context = new SearchContext();
            String text = searchField.getText();
            if (text.length() == 0) {
                return;
            }
            context.setSearchFor(text);
            context.setMatchCase(matchCaseCB.isSelected());
            context.setRegularExpression(regexCB.isSelected());
            context.setSearchForward(e.getSource() == nextButton);
            context.setWholeWord(false);

            boolean found = SearchEngine.find(textArea, context).wasFound();
            if (!found) {
                JOptionPane.showMessageDialog(panel, "Text not found!");
            }
        }
    }

}
